#include "Media/Sync/sync.h"
#include <QDebug>
#include <QImage>
#include <QTimer>
extern "C" {
#include <libswscale/swscale.h>
}
AVSync::AVSync():time_timer(nullptr),m_sync_status(SyncStatus::Null){
    //init buffer
    try{
        video_buffer = new CircularBuffer<AVFrame>(3000);
        audio_buffer = new CircularBuffer<AVFrame>(3000);
    }
    catch (const std::bad_alloc& e) {
           std::cerr << "Memory allocation failed: " << e.what() << std::endl;
    } catch (const std::exception& e) {
           std::cerr << "Exception: " << e.what() << std::endl;
    } catch (...) {
           std::cerr << "Unknown exception caught" << std::endl;
    }
    //set timer to check sync status
    time_timer = new QTimer(this);
    time_timer->setInterval(1000);
    time_timer->setSingleShot(false);
    time_timer->setTimerType(Qt::PreciseTimer);
    connect(time_timer, &QTimer::timeout, this, &AVSync::updateCurrentTime);
    OptimizationManager::getInstance().init();
    OptimizationManager::getInstance().setStrategy("DoubleBufferingStrategy");
}
//set updateCurrentTime slot
void AVSync::updateCurrentTime(){

}
AVSync::~AVSync(){
    audio_buffer->clear();
    delete audio_buffer;
    video_buffer->clear();
    delete video_buffer;
}
void AVSync::init(){
    std::cout << "AVSync init: video_buffer size: " << video_buffer->size() << std::endl;
    std::cout << "AVSync init: audio_buffer size: " << audio_buffer->size() << std::endl;
}
// 将解码后的音频帧添加到音频缓冲区。
void AVSync::add_audio_frame(AVFrame * audio_frame){
    AVFrame* cloned_frame = av_frame_clone(audio_frame);
//    AVFrame&& rvalue_ref = std::move(*audio_frame);
    audio_buffer->push(cloned_frame);
//  qDebug()<<"audio_buffer"<<audio_buffer->size();
}


// 将解码后的视频帧添加到视频缓冲区。
void AVSync::add_video_frame(AVFrame *vedio_frame){
    AVFrame* cloned_frame = av_frame_clone(vedio_frame);
    video_buffer->push(cloned_frame);
//  qDebug()<<"add_video_frame"<<video_buffer->size();
}



// 启动音视频同步处理。
void AVSync::start(){
    std::cout << "AVSync start" << std::endl;
    time_timer->start();
    m_sync_status = SyncStatus::Busy;
}

// 停止音视频同步处理。
void AVSync::stop(){
    audio_buffer->clear();
    video_buffer->clear();
}
void AVSync::sendQImage(){
        AVFrame & frame = video_buffer->pop();

        QImage img = frameToQImage(&frame);
        {
            std::lock_guard<std::mutex> lock(mutex_);
 //           frameQueue_.push(img);
            if(img.isNull()){
                std::cout << "Warning: QImage is null" << std::endl;
            }
            else{
 //               std::cout << "QImage size: " << img.size().width() << "x" << img.size().height() << std::endl;
            }
            emit newFrame(img);
        //    cv_.notify_one();
        }
}
QImage AVSync::frameToQImage(const AVFrame* frame) {
    int width = frame->width;
    int height = frame->height;
    QImage img(width, height, QImage::Format_RGB32);
    SwsContext* sws_ctx = sws_getContext(width, height, static_cast<AVPixelFormat>(frame->format), width, height, AV_PIX_FMT_RGB32, SWS_BILINEAR, nullptr, nullptr, nullptr);
    uint8_t* data[1] = { reinterpret_cast<uint8_t*>(img.bits()) };
    int linesize[1] = { static_cast<int>(img.bytesPerLine()) };
    sws_scale(sws_ctx, frame->data, frame->linesize, 0, height, data, linesize);
    sws_freeContext(sws_ctx);
    return img;
}

//QImage AVSync::getFrame() {
//    // std::unique_lock<std::mutex> lock(mutex_);
//    // cv_.wait(lock, [this] { return !frameQueue_.empty(); });
//    // QImage img = frameQueue_.front();
//    // frameQueue_.pop();
//    QImage img;
//     return img;
//}
